/*
* Copyright 2012-2013 Alfresco Software Limited.
*
* Licensed under the GNU Affero General Public License, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/agpl-3.0.html
*
* If you do not wish to be bound to the terms of the AGPL v3.0,
* A commercial license may be obtained by contacting the author.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of an unsupported extension to Alfresco.
*
*/
package org.alfresco.extension.countersign.signature;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.security.auth.x500.X500Principal;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.extension.countersign.model.CounterSignSignatureModel;
import org.alfresco.extension.countersign.service.CounterSignService;
import org.alfresco.model.ContentModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
public class RepositoryManagedSignatureProvider implements SignatureProvider
{
private static Log logger = LogFactory.getLog(RepositoryManagedSignatureProvider.class);
private ServiceRegistry serviceRegistry;
private String user;
private Properties config;
private CounterSignService counterSignService;
public RepositoryManagedSignatureProvider(ServiceRegistry serviceRegistry,
CounterSignService counterSignService, String user, Properties config)
{
this.config = config;
this.serviceRegistry = serviceRegistry;
this.user = user;
this.counterSignService = counterSignService;
// check to see if this user has the signer aspect. If not, add it.
// this is temporary until I get the management interface sorted out.
if(!signatureAvailable())
{
NodeRef person = serviceRegistry.getPersonService().getPerson(user);
if(person != null)
{
serviceRegistry.getNodeService().addAspect(person, CounterSignSignatureModel.ASPECT_SIGNER, null);
}
}
}
@Override
public KeyStore getUserKeyStore(String storePassword)
{
try
{
NodeRef person = serviceRegistry.getPersonService().getPerson(user);
if(person == null)
{
return null;
}
KeyStore keystore = KeyStore.getInstance("pkcs12");
// check to see if a keystore exists for this user
NodeRef keystoreNode = counterSignService.getSignatureArtifact(person, CounterSignSignatureModel.ASSOC_SIGNERKEYSTORE);
// if no keystore, create one, persist it and associate it with the user
if(keystoreNode == null)
{
keystore = createUserKeyStore(person, storePassword);
}
else
{
// open the reader to the key and load it
ContentReader keyReader = serviceRegistry.getContentService().getReader(keystoreNode, ContentModel.PROP_CONTENT);
keystore.load(keyReader.getContentInputStream(), storePassword.toCharArray());
}
// return the keystore
return keystore;
}
catch(KeyStoreException kse)
{
throw new AlfrescoRuntimeException(kse.getMessage());
}
catch (java.security.cert.CertificateException ce)
{
throw new AlfrescoRuntimeException(ce.getMessage());
}
catch(NoSuchAlgorithmException nsaex)
{
throw new AlfrescoRuntimeException(nsaex.getMessage());
}
catch (IOException ioex)
{
throw new AlfrescoRuntimeException(ioex.getMessage());
}
catch (NoSuchProviderException nspex)
{
throw new AlfrescoRuntimeException(nspex.getMessage());
}
}
@Override
public BufferedImage getSignatureImage()
{
NodeRef person = serviceRegistry.getPersonService().getPerson(user);
if(person == null)
{
return null;
}
NodeRef sigImage = counterSignService.getSignatureArtifact(person, CounterSignSignatureModel.ASSOC_SIGNERSIGNATUREIMAGE);
if(sigImage != null)
{
ContentReader imageReader = serviceRegistry.getContentService().getReader(sigImage, ContentModel.PROP_CONTENT);
try
{
return ImageIO.read(imageReader.getContentInputStream());
}
catch(IOException ioex)
{
logger.warn("Could not retrieve signature image as a child of person: " + ioex);
// generate a default image?
}
}
return null;
}
@Override
public String getSignatureSource()
{
NodeRef person = serviceRegistry.getPersonService().getPerson(user);
if(person == null)
{
return null;
}
NodeRef sigImage = counterSignService.getSignatureArtifact(person, CounterSignSignatureModel.ASSOC_SIGNERSIGNATUREIMAGE);
if(sigImage != null)
{
return String.valueOf(
serviceRegistry.getNodeService().getProperty(sigImage, CounterSignSignatureModel.PROP_SIGNATUREJSON));
}
return null;
}
@Override
public void saveSignatureImage(BufferedImage image, String source)
{
// save the signature image as a child of the person
NodeRef person = serviceRegistry.getPersonService().getPerson(user);
if(person != null)
{
NodeRef sigNode = counterSignService.getSignatureArtifact(person, CounterSignSignatureModel.ASSOC_SIGNERSIGNATUREIMAGE);
if(sigNode == null)
{
// set up JSON source as property
Map<QName, Serializable> sigProps = new HashMap<QName, Serializable>();
sigProps.put(CounterSignSignatureModel.PROP_SIGNATUREJSON, source);
QName assocQName = QName.createQName(
CounterSignSignatureModel.COUNTERSIGN_SIGNATURE_MODEL_1_0_URI,
QName.createValidLocalName(user + "-signatureimage"));
ChildAssociationRef sigChildRef = serviceRegistry.getNodeService().createNode(
person,
CounterSignSignatureModel.ASSOC_SIGNERSIGNATUREIMAGE,
assocQName,
CounterSignSignatureModel.TYPE_SIGNATUREIMAGE,
sigProps);
sigNode = sigChildRef.getChildRef();
}
else
{
serviceRegistry.getNodeService().setProperty(sigNode, CounterSignSignatureModel.PROP_SIGNATUREJSON, source);
}
// get a writer, store the image content
ContentWriter writer = serviceRegistry.getContentService().
getWriter(sigNode, ContentModel.PROP_CONTENT, true);
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
writer.putContent(new ByteArrayInputStream(baos.toByteArray()));
PermissionService ps = serviceRegistry.getPermissionService();
ps.clearPermission(sigNode, PermissionService.ALL_AUTHORITIES);
ps.setInheritParentPermissions(sigNode, false);
}
catch(IOException ioex)
{
logger.warn("Could not save signature image as child of person: " + ioex);
}
}
}
@Override
public boolean signatureAvailable()
{
// signature is only available if this user has the "signer" aspect applied.
NodeRef person = serviceRegistry.getPersonService().getPerson(user);
if(person != null && serviceRegistry.getNodeService().hasAspect(person, CounterSignSignatureModel.ASPECT_SIGNER))
{
// now check to see if the user has a keystore available. If so, then
// they can sign without creating a new keystore.
NodeRef keystoreNode = counterSignService.getSignatureArtifact(person, CounterSignSignatureModel.ASSOC_SIGNERKEYSTORE);
if(keystoreNode != null && serviceRegistry.getNodeService().exists(keystoreNode))
{
return true;
}
}
return false;
}
/**
* Get the user's public key
*
*/
public PublicKey getPublicKey()
{
NodeRef person = serviceRegistry.getPersonService().getPerson(user);
NodeRef keyNode = counterSignService.getSignatureArtifact(person, CounterSignSignatureModel.ASSOC_SIGNERPUBLICKEY);
if(keyNode != null)
{
PEMReader parser = null;
try
{
ContentReader keyReader = serviceRegistry.getContentService().getReader(keyNode, ContentModel.PROP_CONTENT);
parser = new PEMReader(new InputStreamReader(keyReader.getContentInputStream()));
PublicKey key = (PublicKey)parser.readObject();
parser.close();
return key;
}
catch(Exception ioex)
{
logger.warn("Error reading user public key: " + ioex.getLocalizedMessage());
}
finally
{
try {if(parser != null) parser.close();}
catch(IOException ioex){logger.warn("Error closing PEMReader");}
}
}
return null;
}
@Override
public boolean validateSignature(byte[] sig, byte[] hash)
{
String alg = config.getProperty(RepositoryManagedSignatureProviderFactory.SIGNATURE_ALGORITHM);
String prov = config.getProperty(RepositoryManagedSignatureProviderFactory.JAVA_SIGNATURE_PROVIDER);
boolean valid = false;
try
{
Signature validate = Signature.getInstance(alg, prov);
validate.initVerify(getPublicKey());
validate.update(hash);
valid = validate.verify(sig);
}
catch(NoSuchProviderException nspe)
{
throw new AlfrescoRuntimeException("Provider: " + prov + " was not found: " + nspe.getMessage());
}
catch (NoSuchAlgorithmException nsae)
{
throw new AlfrescoRuntimeException("Algorithm: " + alg + " is not available: " + nsae.getMessage());
}
catch(SignatureException se)
{
valid = false;
}
catch(InvalidKeyException ike)
{
valid = false;
}
return valid;
}
/**
* Sign a hash using the user's private key
*
* @param hash
* @param key
* @return
* @throws Exception
*/
public byte[] signHash(byte[] hash, String password) throws Exception {
String alg = config.getProperty(RepositoryManagedSignatureProviderFactory.SIGNATURE_ALGORITHM);
String prov = config.getProperty(RepositoryManagedSignatureProviderFactory.JAVA_SIGNATURE_PROVIDER);
String alias = config.getProperty(RepositoryManagedSignatureProviderFactory.ALIAS);
KeyStore ks = getUserKeyStore(password);
PrivateKey key = (PrivateKey)ks.getKey(alias, password.toCharArray());
Signature signer = Signature.getInstance(alg, prov);
signer.initSign(key);
signer.update(hash);
return signer.sign();
}
/**
* Compute a hash of the input stream using the configured algorithm
*
* @param contentSteam
* @return a hash of the content stream
*/
public byte[] computeHash(InputStream contentStream) {
String alg = config.getProperty(RepositoryManagedSignatureProviderFactory.HASH_ALGORITHM);
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance(alg);
} catch (NoSuchAlgorithmException e) {
logger.error("Unable to process algorithm type: " + alg);
return null;
}
messageDigest.reset();
byte[] buffer = new byte[1024];
int bytesRead = -1;
try {
while ((bytesRead = contentStream.read(buffer)) > -1) {
messageDigest.update(buffer, 0, bytesRead);
}
} catch (IOException e) {
logger.error("Unable to read content stream.", e);
return null;
} finally {
try {
contentStream.close();
} catch (IOException e) {}
}
byte[] digest = messageDigest.digest();
return convertByteArrayToHex(digest).getBytes();
}
private String convertByteArrayToHex(byte[] array) {
StringBuffer hashValue = new StringBuffer();
for (int i = 0; i < array.length; i++) {
String hex = Integer.toHexString(0xFF & array[i]);
if (hex.length() == 1) {
hashValue.append('0');
}
hashValue.append(hex);
}
return hashValue.toString().toUpperCase();
}
/**
* Save the user's public key, associated as a child with the person
* that owns it. Make this world-readable, as anybody should be able
* to use it for validating signatures.
*
* @param person
* @param publicKey
*/
private void saveUserPublicKey(NodeRef person, PublicKey publicKey)
{
NodeRef keyNode = counterSignService.getSignatureArtifact(person, CounterSignSignatureModel.ASSOC_SIGNERPUBLICKEY);
if(keyNode == null)
{
QName assocQName = QName.createQName(
CounterSignSignatureModel.COUNTERSIGN_SIGNATURE_MODEL_1_0_URI,
QName.createValidLocalName(user + "-publickey"));
ChildAssociationRef keyChildRef = serviceRegistry.getNodeService().createNode(
person,
CounterSignSignatureModel.ASSOC_SIGNERPUBLICKEY,
assocQName,
CounterSignSignatureModel.TYPE_PUBLICKEY);
keyNode = keyChildRef.getChildRef();
}
// get a writer, store the public key
ContentWriter writer = serviceRegistry.getContentService().
getWriter(keyNode, ContentModel.PROP_CONTENT, true);
PEMWriter pem = null;
try
{
//set the encoding and write out the key
serviceRegistry.getNodeService().setProperty(keyNode, CounterSignSignatureModel.PROP_KEYENCODING, "PEM");
pem = new PEMWriter(new OutputStreamWriter(writer.getContentOutputStream()));
pem.writeObject(publicKey);
}
catch(IOException ioex)
{
logger.error("Error writing public key to PEMWriter: " + ioex);
}
finally
{
if(pem != null) try{pem.close();}catch(Exception ex) {logger.error("Error closing PEMWriter");}
}
// Ensure that the cert is readable by anybody, this is important
// for later validation of signed content. Can't validate without the
// public key
PermissionService ps = serviceRegistry.getPermissionService();
ps.setPermission(keyNode, PermissionService.ALL_AUTHORITIES, PermissionService.READ, true);
ps.setInheritParentPermissions(keyNode, false);
}
/**
* Save the Java KeyStore, associated as a child with the person that owns this keystore
*
* @param person
* @param keystore
* @throws IOException
* @throws CertificateException
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
*/
private void saveUserKeyStore(NodeRef person, KeyStore keystore, String password)
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException
{
NodeRef keystoreNode = counterSignService.getSignatureArtifact(person, CounterSignSignatureModel.ASSOC_SIGNERKEYSTORE);
if(keystoreNode == null)
{
QName assocQName = QName.createQName(
CounterSignSignatureModel.COUNTERSIGN_SIGNATURE_MODEL_1_0_URI,
QName.createValidLocalName(user + "-signaturekeystore"));
ChildAssociationRef keyChildRef = serviceRegistry.getNodeService().createNode(
person,
CounterSignSignatureModel.ASSOC_SIGNERKEYSTORE,
assocQName,
CounterSignSignatureModel.TYPE_PKCS12);
keystoreNode = keyChildRef.getChildRef();
}
// get a writer, store the user keystore
ContentWriter writer = serviceRegistry.getContentService().
getWriter(keystoreNode, ContentModel.PROP_CONTENT, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
keystore.store(baos, password.toCharArray());
writer.putContent(new ByteArrayInputStream(baos.toByteArray()));
// now set the permissions on this node so that only the person that owns it
// can access it. PermissionService.ALL_AUTHORITIES = GROUP_EVERYONE
// this should leave the owner permissions intact
PermissionService ps = serviceRegistry.getPermissionService();
ps.clearPermission(keystoreNode, PermissionService.ALL_AUTHORITIES);
ps.setInheritParentPermissions(keystoreNode, false);
}
/**
* Create a keystore for this user to be used for document signing, store it associated with the user's
* person node
*
* @param person
* @param password
*
* @return a Java KeyStore object suitable for document signing
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws KeyStoreException
* @throws IOException
* @throws CertificateException
*/
private KeyStore createUserKeyStore(NodeRef person, String password)
throws NoSuchAlgorithmException, NoSuchProviderException, KeyStoreException, CertificateException, IOException
{
// get the alias from the configuration
String alias = config.getProperty(RepositoryManagedSignatureProviderFactory.ALIAS);
// initialize key generator
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(2048, random);
// generate a keypair
KeyPair pair = keyGen.generateKeyPair();
PrivateKey priv = pair.getPrivate();
PublicKey pub = pair.getPublic();
Certificate[] certChain = getCertChain(pair, person);
// create keystore, adding private key and cert chain
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(null, password.toCharArray());
ks.setKeyEntry(alias, priv, password.toCharArray(), certChain);
// save the keystore
saveUserKeyStore(person, ks, password);
// also save the public key separately, will need it
// for later validaiton activities
saveUserPublicKey(person, pub);
// return the generated keystore
return ks;
}
/**
* Get a certificate chain, given a person and a keypair
* @param pair
* @param person
* @return
*/
private Certificate[] getCertChain(KeyPair pair, NodeRef person)
{
boolean generateTrusted = Boolean.parseBoolean(config.getProperty(RepositoryManagedSignatureProviderFactory.ENABLE_TRUSTED_CERTS));
Certificate[] certChain;
// generate the user certificate
Certificate cert = generateCertificate(pair, person, generateTrusted);
// create a trusted cert chain if enabled
if(generateTrusted)
{
// get the ca cert used to sign and create cert chain
KeyStore trustedKs = getTrustedKeyStore();
Certificate[] caChain = getCaCertChain(trustedKs);
certChain = new Certificate[caChain.length + 1];
certChain[0] = cert;
for(int i = 0; i < caChain.length; i++)
{
certChain[i+1] = caChain[i];
}
}
else
{
certChain = new Certificate[1];
certChain[0] = cert;
}
return certChain;
}
/**
* Generate an X509 cert for use as the keystore cert chain
*
* @param keyPair
* @return
*/
private X509Certificate generateCertificate(KeyPair keyPair, NodeRef person, boolean trusted)
{
X509Certificate cert = null;
int validDuration = Integer.parseInt(config.getProperty(RepositoryManagedSignatureProviderFactory.VALID_DURATION));
// get user's first and last name
Map<QName, Serializable> props = serviceRegistry.getNodeService().getProperties(person);
String firstName = String.valueOf(props.get(ContentModel.PROP_FIRSTNAME));
String lastName = String.valueOf(props.get(ContentModel.PROP_LASTNAME));
// backdate the start date by a day
Calendar start = Calendar.getInstance();
start.add(Calendar.DATE, -1);
java.util.Date startDate = start.getTime();
// what is the end date for this cert's validity?
Calendar end = Calendar.getInstance();
end.add(Calendar.DATE, validDuration);
java.util.Date endDate = end.getTime();
try
{
// This code works with newer versions of the BouncyCastle libraries, but not
// the (severely outdated) version that ships with Alfresco
/*X509v1CertificateBuilder certBuilder = new JcaX509v1CertificateBuilder(
new X500Principal("CN=" + firstName + " " + lastName),
BigInteger.ONE,
startDate, cal.getTime(),
new X500Principal("CN=" + firstName + " " + lastName),
keyPair.getPublic());
AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA");
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
AsymmetricKeyParameter keyParam = PrivateKeyFactory.createKey(keyPair.getPrivate().getEncoded());
ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(keyParam);
X509CertificateHolder certHolder = certBuilder.build(sigGen);
// now lets convert this thing back to a regular old java cert
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream certIs = new ByteArrayInputStream(certHolder.getEncoded());
cert = (X509Certificate) cf.generateCertificate(certIs);
certIs.close();*/
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
X500Principal subjectName = new X500Principal("CN=" + firstName + " " + lastName);
certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
certGen.setNotBefore(startDate);
certGen.setNotAfter(endDate);
certGen.setSubjectDN(subjectName);
certGen.setPublicKey(keyPair.getPublic());
certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
// if we are actually generating a trusted cert, the action is a little different
if(trusted)
{
KeyStore trustedKs = getTrustedKeyStore();
PrivateKey caKey = getCaKey(trustedKs);
X509Certificate caCert = getCaCert(trustedKs);
// set the issuer of the generated cert to the subject of the ca cert
X500Principal caSubject = caCert.getSubjectX500Principal();
certGen.setIssuerDN(caSubject);
//add the required extensions for the new cert
certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
new AuthorityKeyIdentifierStructure(caCert));
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
new SubjectKeyIdentifierStructure(keyPair.getPublic()));
cert = certGen.generate(caKey, "BC");
//verify the cert
cert.verify(caCert.getPublicKey());
}
else
{
certGen.setIssuerDN(subjectName);
cert = certGen.generate(keyPair.getPrivate(), "BC");
}
}
catch(CertificateException ce)
{
logger.error("CertificateException creating or validating X509 certificate for user: " + ce);
throw new AlfrescoRuntimeException(ce.getMessage());
}
catch(Exception ex)
{
logger.error("Unknown exception creating or validating X509 certificate for user : " + ex);
ex.printStackTrace();
}
return cert;
}
/**
* Get the Certificate Authority private key
*
* @return
*/
private PrivateKey getCaKey(KeyStore trustedKs)
{
PrivateKey caKey = null;
String keyAlias = config.getProperty(RepositoryManagedSignatureProviderFactory.TRUSTED_KEY_ALIAS);
String keyPassword = config.getProperty(RepositoryManagedSignatureProviderFactory.TRUSTED_KEY_PASSWORD);
try
{
caKey = (PrivateKey)trustedKs.getKey(keyAlias, keyPassword.toCharArray());
}
catch(KeyStoreException kse)
{
throw new AlfrescoRuntimeException(kse.getMessage());
}
catch(UnrecoverableKeyException uke)
{
throw new AlfrescoRuntimeException(uke.getMessage());
}
catch(NoSuchAlgorithmException nsae)
{
throw new AlfrescoRuntimeException(nsae.getMessage());
}
return caKey;
}
/**
* Get the Certificate Authority public key certificate
*
* @return
*/
private X509Certificate getCaCert(KeyStore trustedKs)
{
X509Certificate caCert = null;
String certAlias = config.getProperty(RepositoryManagedSignatureProviderFactory.TRUSTED_CERT_ALIAS);
try
{
caCert = (X509Certificate)trustedKs.getCertificate(certAlias);
}
catch(KeyStoreException kse)
{
throw new AlfrescoRuntimeException(kse.getMessage());
}
return caCert;
}
/**
* Get the certificate chain for the CA certificate
*
* @param trustedKs
* @return
*/
private Certificate[] getCaCertChain(KeyStore trustedKs)
{
Certificate[] caCertChain = null;
String certAlias = config.getProperty(RepositoryManagedSignatureProviderFactory.TRUSTED_CERT_ALIAS);
try
{
caCertChain = trustedKs.getCertificateChain(certAlias);
}
catch(KeyStoreException kse)
{
throw new AlfrescoRuntimeException(kse.getMessage());
}
return caCertChain;
}
/**
* Get the trusted keystore as configured in the extension properties.
*
* @return
*/
private KeyStore getTrustedKeyStore()
{
try
{
String keystorePassword = config.getProperty(RepositoryManagedSignatureProviderFactory.TRUSTED_KEYSTORE_PASSWORD);
String keystorePath = config.getProperty(RepositoryManagedSignatureProviderFactory.TRUSTED_KEYSTORE_PATH);
KeyStore keystore = KeyStore.getInstance("pkcs12");
FileInputStream keyStream = new FileInputStream(keystorePath);
keystore.load(keyStream, keystorePassword.toCharArray());
// return the keystore
return keystore;
}
catch(KeyStoreException kse)
{
throw new AlfrescoRuntimeException(kse.getMessage());
}
catch (java.security.cert.CertificateException ce)
{
throw new AlfrescoRuntimeException(ce.getMessage());
}
catch(NoSuchAlgorithmException nsaex)
{
throw new AlfrescoRuntimeException(nsaex.getMessage());
}
catch (IOException ioex)
{
throw new AlfrescoRuntimeException(ioex.getMessage());
}
}
public void setServiceRegistry(ServiceRegistry serviceRegistry)
{
this.serviceRegistry = serviceRegistry;
}
}